﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Text;
using DataLayer;

public partial class tab_share : System.Web.UI.Page
{
   int TabId
   {
      get
      {
         int result = -1;
         try
         {
            result = Convert.ToInt32(Request.QueryString["id"]);
         }
         catch
         {
         }
         return result;
      }
   }
   protected override PageStatePersister PageStatePersister
   {
      get
      {
         return new SessionPageStatePersister(this.Page);
      }
   }

   protected DataTable tbl_AccessRights
   {
      get
      {
         DataTable tbl = (DataTable)ViewState["TBL"];
         if (tbl == null)
         {
            tbl = new DataTable("tbl");
            tbl.Columns.Add("DisplayName");
            tbl.Columns.Add("UserName");
            tbl.Columns.Add("Email");
            tbl.Columns.Add("UserID");
            tbl.Columns.Add("isRole", typeof(bool));
            tbl.Columns.Add("Tab_EditName", typeof(bool));
            tbl.Columns.Add("Tab_Read", typeof(bool));
            tbl.Columns.Add("Tab_Share", typeof(bool));
            tbl.Columns.Add("Tab_Delete", typeof(bool));
            tbl.Columns.Add("Tab_AddWidgets", typeof(bool));
            tbl.Columns.Add("Tab_ChangeLayout", typeof(bool));
            tbl.Columns.Add("Tab_ChangeTheme", typeof(bool));
            tbl.Columns.Add("Widget_Edit", typeof(bool));
            tbl.Columns.Add("Widget_Reorder", typeof(bool));
            tbl.Columns.Add("Widget_Delete", typeof(bool));
            tbl.Columns.Add("Widget_EditTitle", typeof(bool));
            tbl.Columns.Add("Basic");
            tbl.Columns.Add("tmp", typeof(bool));
            tbl_AccessRights = tbl;
         }
         
         return tbl;
      }
      set
      {
         ViewState["TBL"] = value;
      }
   }

   protected string getFixedMessage(string TabTitle, string URL, string Permissions)
   {
      return String.Format(@"
{0} ({1}) has granted you access to [{2}] tab in Nexus.
<br />Click the link below to add it to your space.
<br /><a href='http://nexus.nus.edu.sg/tab_addshare.aspx?{3}'>http://nexus.nus.edu.sg/tab_addshare.aspx?{3}</a>
<br />You have been granted access to the tab with the following permissions: 
<br />{4}
", Profile.Fullname, Profile.UserName, TabTitle, URL, Permissions);
   }


   protected string getFixedMessage2(string TabTitle, string URL, string Permissions)
   {
      return String.Format(@"
{0} ({1}) has granted you access to [{2}] tab in Nexus.
<br />You have been granted access to the tab with the following permissions: 
<br />{4}
", Profile.Fullname, Profile.UserName, TabTitle, URL, Permissions);
   }

   protected void Page_Load(object sender, EventArgs e)
   {
      //Requirement: Tab must belong to the person, or person has admin rights
      if (!TabAccessLevelFunctions.UserHasPermission(Profile.UserName, TabId, TabAccessLevel.Tab_Share))
      {
         if (TabId > 0)
         {
            //if valid tabid given, 
            ClientScript.RegisterStartupScript(Page.GetType(), "Invalid",
               "alert('You do not have permission to perform this action');opener.myTabs.ResetTab(" + TabId + ");window.close();",
               true);
         }
         else
         {
            //if invalid tabid, force a reload of everything
            ClientScript.RegisterStartupScript(Page.GetType(), "Invalid",
               "alert('You do not have permission to perform this action');myTabs.FirstLoad();window.close();",
               true);
         }
         Panel_Complete.Visible = Panel_Confirm.Visible = Panel_SetAccessRights.Visible = Panel_ShareWithWho.Visible = false;
         return;
      }

      if (!IsPostBack)
      {
         MembershipUser curUser = Membership.GetUser();
         lbl_From.Text = Profile.Fullname + " (" + curUser.Email + ")";
         Panel_SetAccessRights.Visible = false;
         using (var db = DatabaseHelper.GetDashboardData())
         {
            var T = db.Tabs.Where(p => p.ID == TabId).First();
            lbl_Tab.Text = T.Title;
            txt_Subject.Text = "I will like to share my [" + T.Title + "] tab in Nexus with you!";

            lbl_Body.Text = "<br><b>The following text is automatically added to the email</b><br><br />" + getFixedMessage(T.Title, "...", "Read, Edit Tab Name (Actual permission will vary based on selection)");

         }
         //btn_Next1_Click(null, null);
      }
   }
   protected void btn_Next1_Click(object sender, EventArgs e)
   {
      bool hasError = false;
      DataTable tbl = tbl_AccessRights;
      for (var i = 0; i < tbl.Rows.Count; i++)
      {
         tbl.Rows[i]["tmp"] = false;
      }
      
      if (tbl.Rows.Count > 0)
         cb_AdvancedRights.Checked = true;

      StringBuilder sb = new StringBuilder();

      foreach (string s in txt_ShareWith.Text.Split(Environment.NewLine.ToCharArray()))
      {
         var val = s.Trim().ToLower();

         if (val.Length > 0 && val[0] == '*')
            val = val.Substring(1);

         if (val.Length > 0)
         {
            DataRow row = tbl.NewRow();
            row["UserID"] = "";

            if (Regex.Match(val, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*").Success)
            {
               row["UserName"] = "";
               row["Email"] = val.StripIfMore(256);
               row["DisplayName"] = row["Email"];
               row["isRole"] = false;
               sb.Append(val + Environment.NewLine);
            }
            else
            {
               if (val.IndexOf("role:") == 0)
               {
                  //want to give permissions to all members in role
                  val = val.Substring("role:".Length);
                  if (Roles.RoleExists(val))
                  {
                     sb.Append("role:" + val);
                     row["Email"] = row["UserName"] = val.StripIfMore(256);
                     row["DisplayName"] = "Role: " + val.StripIfMore(256);
                     row["isRole"] = true;
                  }
                  else
                  {
                     sb.Append("*role:" + val);
                     hasError = true;
                  }
               }
               else
               {
                  LdapUser UserInfo = new LdapUser(val);
                  row["UserID"] = row["UserName"] = UserInfo.UserID;
                  if (UserInfo.UserLdapType == UserType.Guest)
                  {
                     //no matching user type, move around the various ldap and see
                     UserInfo.UserLdapType = UserType.NUSStudent;
                     row["Email"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "mail");

                     if (row["Email"].ToString().Length < 1)
                     {
                        UserInfo.UserLdapType = UserType.NUSStaff;
                        row["Email"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "mail");
                     }
                     else
                     {
                        row["UserID"] = @"NUSSTU\" + val;
                        row["UserName"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "displayName");
                     }

                     if (row["Email"].ToString().Length < 1)
                     {
                        UserInfo.UserLdapType = UserType.NUSAlumni;
                        row["Email"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "mail");
                        if (row["Email"].ToString().Length > 0)
                        {
                           row["UserName"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "displayName");
                           row["UserID"] = @"NUSALM\" + val;
                        }
                     }
                     else
                     {
                        row["UserName"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "displayName");
                        row["UserID"] = @"NUSSTF\" + val;
                     }
                  }
                  else
                  {
                     row["Email"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "mail");
                     row["UserName"] = NexusMembershipProvider.GetLdapProperty(UserInfo, "displayName");
                  }
                  row["Email"] = row["Email"].ToString().StripIfMore(256);
                  row["UserName"] = row["UserName"].ToString().StripIfMore(256);

                  if (row["Email"].ToString().Length > 0)
                  {
                     row["DisplayName"] = "<a href='mailto:" + row["Email"].ToString().Replace("'", "''") + "'>" + row["UserName"] + "</a>";
                     sb.Append(val + Environment.NewLine);
                  }
                  else
                  {
                     row["DisplayName"] = "";
                     row["Email"] = "";
                     row["UserName"] = "";
                     sb.Append("*" + val + Environment.NewLine);
                     hasError = true;
                  }
                  row["isRole"] = false;                  
               }
            }

            if (row["Email"].ToString().Length > 0)
            {
               DataRow[] Rows = tbl.Select("Email='" + row["Email"].ToString().Replace("'", "''") + "'");
               if (Rows.Length < 1)
               {
                  //need to confirm that no such person exists in existing system

                  row["Tab_EditName"] = false;
                  row["Tab_Share"] = false;
                  row["Tab_Read"] = true;
                  row["Tab_Delete"] = false;
                  row["Tab_AddWidgets"] = false;
                  row["Tab_ChangeLayout"] = false;
                  row["Tab_ChangeTheme"] = false;
                  row["Widget_Edit"] = false;
                  row["Widget_Reorder"] = false;
                  row["Widget_Delete"] = false;
                  row["Widget_EditTitle"] = false;
                  row["tmp"] = true;
                  tbl.Rows.Add(row);
               }
               else
               {
                  foreach (DataRow dr in Rows)
                  {
                     dr["tmp"] = true;
                  }
               }
            }
         }
      }

      for(int i=0;i<tbl.Rows.Count;i++)
      {
         DataRow row = tbl.Rows[i];
         if (!(bool)row["tmp"])
         {
            tbl.Rows.Remove(row);
            i--;
         }
      }
      tbl_AccessRights = tbl;
      txt_ShareWith.Text = sb.ToString();

      if (hasError)
      {
         lbl_Error.Visible = true;
      }
      else
      {
         Panel_SetAccessRights.Visible = true;
         Panel_ShareWithWho.Visible = false;
         lbl_Error.Visible = false;

         DataView DV = new DataView();
         DV.Table = tbl;
         DV.Sort = "DisplayName";
         GV_AccessRights.DataSource = DV;
         GV_AccessRights.DataBind();

         ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "permission", "ShowAdvancedRights($get('" + cb_AdvancedRights.ClientID + "'));", true);
      }
   }

   protected void SavePermission()
   {
      DataTable tbl = tbl_AccessRights;
      for(int i=0;i<GV_AccessRights.Rows.Count;i++)
      {
         GridViewRow Row = GV_AccessRights.Rows[i];
         if (Row.RowType == DataControlRowType.DataRow)
         {
            string Key = GV_AccessRights.DataKeys[Row.RowIndex].Value.ToString();
            DataRow[] Rows = tbl.Select("Email='" + Key.ToString().Replace("'", "''") + "'");
            if (Rows.Length > 0)
            {
               foreach (DataRow row in Rows)
               {
                  row["Tab_Read"] = (Row.FindControl("cb_Read") as CheckBox).Checked;
                  row["Tab_EditName"] = (Row.FindControl("cb_Tab_EditName") as CheckBox).Checked;
                  row["Tab_Share"] = (Row.FindControl("cb_Tab_Share") as CheckBox).Checked;
                  row["Tab_Delete"] = (Row.FindControl("cb_Tab_Delete") as CheckBox).Checked;
                  row["Tab_AddWidgets"] = (Row.FindControl("cb_Tab_AddWidgets") as CheckBox).Checked;
                  row["Tab_ChangeLayout"] = (Row.FindControl("cb_Tab_ChangeLayout") as CheckBox).Checked;
                  row["Tab_ChangeTheme"] = (Row.FindControl("cb_Tab_ChangeTheme") as CheckBox).Checked;
                  row["Widget_Edit"] = (Row.FindControl("cb_Widget_Edit") as CheckBox).Checked;
                  row["Widget_Reorder"] = (Row.FindControl("cb_Widget_Reorder") as CheckBox).Checked;
                  row["Widget_Delete"] = (Row.FindControl("cb_Widget_Delete") as CheckBox).Checked;
                  row["Widget_EditTitle"] = (Row.FindControl("cb_Widget_EditTitle") as CheckBox).Checked;
               }
            }
         }
      }
      tbl_AccessRights = tbl;
   }

   protected void btn_Back1_Click(object sender, EventArgs e)
   {
      SavePermission();
      Panel_SetAccessRights.Visible = false;
      Panel_ShareWithWho.Visible = true;
   }

   protected void btn_Back2_Click(object sender, EventArgs e)
   {
      SaveName();
      Panel_ShareWithWho.Visible = true;
      Panel_Confirm.Visible = false;
      //re render the checkboxes just in case..
      btn_Next1_Click(sender, e);
   }

   protected void SaveName()
   {
      DataTable tbl = tbl_AccessRights;
      for (int i = 0; i < GV_Users.Rows.Count; i++)
      {
         GridViewRow Row = GV_Users.Rows[i];
         if (Row.RowType == DataControlRowType.DataRow)
         {
            string Key = GV_Users.DataKeys[Row.RowIndex].Value.ToString();
            DataRow[] Rows = tbl.Select("Email='" + Key.ToString().Replace("'", "''") + "'");
            if (Rows.Length > 0)
            {
               foreach (DataRow row in Rows)
               {
                  string newName = (Row.FindControl("txt_Name") as TextBox).Text;
                  if (newName.Length > 0)
                  {
                     row["UserName"] = newName.StripIfMore(256);
                     row["DisplayName"] = "<a href='mailto:" + row["Email"].ToString().Replace("'", "''") + "'>" + row["UserName"] + "</a>";
                  }
                  else
                  {
                     row["UserName"] = "";
                     row["DisplayName"] = row["Email"].ToString().StripIfMore(256);
                  }
               }
            }
         }
      }
      tbl_AccessRights = tbl;
   }
   
   protected void btn_Confirm_Click(object sender, EventArgs e)
   {
      SavePermission();
      Panel_Confirm.Visible = true;
      Panel_SetAccessRights.Visible = false;

      DataView DV = new DataView();
      DV.Table = tbl_AccessRights;
      DV.Sort = "UserName, Email";
      GV_Users.DataSource = DV;
      GV_Users.DataBind();
   }
   protected void btn_Finish_Click(object sender, EventArgs e)
   {
      SavePermission();

      if (txt_Subject.Text.Length < 1)
         txt_Subject.Text = txt_Subject.Text = "I will like to share my [" + lbl_Tab.Text + "] tab in Nexus with you!"; ;

      string body_personal = txt_Body.Text.Replace(Environment.NewLine, "<br />");
      if (body_personal.Length > 0)
         body_personal += "<br />";

      StringBuilder sb = new StringBuilder();
      StringBuilder lb = new StringBuilder();
      DataTable tbl = tbl_AccessRights;
      using (var db = DatabaseHelper.GetDashboardData())
      {
         foreach (DataRow row in tbl.Rows)
         {
            Guid UserKey = Guid.Empty;
            if ((bool)row["isRole"])
            {
               //if is role, add to the role table if it does not exist
               var obj = new RoleTab();
               obj.RoleID = Functions.GetRoleID(row["Email"].ToString());
               obj.TabId = TabId;
               obj.AccessLevel = TabAccessLevelFunctions.GeneratePermissionLevel(false,
                     (bool)row["Tab_Read"],
                     (bool)row["Tab_EditName"],
                     (bool)row["Tab_Share"],
                     (bool)row["Tab_Delete"],
                     (bool)row["Tab_AddWidgets"],
                     (bool)row["Tab_ChangeLayout"],
                     (bool)row["Tab_ChangeTheme"],
                     (bool)row["Widget_Edit"],
                     (bool)row["Widget_Reorder"],
                     (bool)row["Widget_Delete"],
                     (bool)row["Widget_EditTitle"]);

               var RT = from p in db.RoleTabs
                        where p.TabId == TabId && p.RoleID == obj.RoleID
                        select p;
               if (RT.Count() > 0)
               {
                  sb.Append("ROLE: " + row["Email"] + " already exists<br />");
                  lb.Append("R:" + row["Email"] + ":E|");
               }
               else
               {
                  DatabaseHelper.Insert<RoleTab>(obj);

                  //add the tab to all users with this role..
                  sb.Append("ROLE: " + row["Email"] + " successfully added<br />");
                  lb.Append("R:" + row["Email"] + ":A|");
               }
            }
            else
            {
               if (row["UserID"].ToString().Length > 0)
               {
                  var tUsers = Membership.FindUsersByName(row["UserID"].ToString());

                  if (tUsers.Count > 0)
                  {
                     var en = tUsers.GetEnumerator();
                     en.MoveNext();

                     UserKey = (Guid)(en.Current as MembershipUser).ProviderUserKey;
                  }
                  else
                  {
                     tUsers = Membership.FindUsersByEmail(row["Email"].ToString());
                     if (tUsers.Count > 0)
                     {
                        var en = tUsers.GetEnumerator();
                        en.MoveNext();

                        var theUser = (en.Current as MembershipUser);
                        UserKey = (Guid)theUser.ProviderUserKey;
                        row["UserID"] = theUser.UserName;
                     }
                  }
               }

               if (UserKey == Guid.Empty)
               {
                  //need to see if there is an existing one for this tab and this email, if there
                  //is, delete tt one first

                  var rTSAs = from p in db.Tab_ShareActivations
                             where p.TabID == TabId && p.Email == row["Email"].ToString()
                             select p;
                  foreach (var x in rTSAs)
                  {
                     DatabaseHelper.Delete<Tab_ShareActivation>(x);
                  }
                     

                  var obj = new Tab_ShareActivation();
                  obj.Email = row["Email"].ToString();
                  obj.EmailContent = "";
                  obj.EmailDate = DateTime.Now;
                  obj.UserName = row["UserName"].ToString();
                  obj.TabID = TabId;
                  obj.AccessLevel = TabAccessLevelFunctions.GeneratePermissionLevel(false,
      (bool)row["Tab_Read"],
      (bool)row["Tab_EditName"],
      (bool)row["Tab_Share"],
      (bool)row["Tab_Delete"],
      (bool)row["Tab_AddWidgets"],
      (bool)row["Tab_ChangeLayout"],
      (bool)row["Tab_ChangeTheme"],
      (bool)row["Widget_Edit"],
      (bool)row["Widget_Reorder"],
      (bool)row["Widget_Delete"],
      (bool)row["Widget_EditTitle"]);

                  DatabaseHelper.Insert<Tab_ShareActivation>(obj);
                  string Permissions = "";
                  foreach (TabAccessLevel lvl in TabAccessLevelFunctions.GetAccessLevels(obj.AccessLevel))
                  {
                     Permissions += lvl.ToString().Replace("_", " ") + ", ";
                  }
                  if (Permissions.Length > 0)
                  {
                     Permissions = Permissions.Substring(0, Permissions.Length - 2);
                  }

                  obj.EmailContent = body_personal + getFixedMessage(lbl_Tab.Text, obj.ID.ToString(), Permissions);
                  //send out the email
                  Email.SendMail(obj.Email, txt_Subject.Text, obj.EmailContent, true);

                  sb.Append("User: " + row["UserName"] + " (" + row["Email"] + ") successfully emailed<br />");
                  lb.Append("U:" + row["UserName"] + ":" + row["Email"] + ":A|");
               }
               else
               {
                  //user already exists in system, add this straight in to his tab
                  //but if he already has this tab, his permission is changed
                  var ut = from p in db.UserTabs
                           where p.UserID == UserKey && p.TabId == TabId
                           select p;

                  if (ut.Count() < 1)
                  {
                     var obj = new Tab_ShareActivated();
                     obj.Email = row["Email"].ToString();
                     string Permissions = "";
                     obj.ActivateDate = obj.EmailDate = DateTime.Now;
                     obj.UserName = row["UserName"].ToString();
                     obj.TabID = TabId;
                     obj.AccessLevel = TabAccessLevelFunctions.GeneratePermissionLevel(false,
         (bool)row["Tab_Read"],
         (bool)row["Tab_EditName"],
         (bool)row["Tab_Share"],
         (bool)row["Tab_Delete"],
         (bool)row["Tab_AddWidgets"],
         (bool)row["Tab_ChangeLayout"],
         (bool)row["Tab_ChangeTheme"],
         (bool)row["Widget_Edit"],
         (bool)row["Widget_Reorder"],
         (bool)row["Widget_Delete"],
         (bool)row["Widget_EditTitle"]);
                     foreach (TabAccessLevel lvl in TabAccessLevelFunctions.GetAccessLevels(obj.AccessLevel))
                     {
                        Permissions += lvl.ToString().Replace("_", " ") + ", ";
                     }

                     if (Permissions.Length > 0)
                     {
                        Permissions = Permissions.Substring(0, Permissions.Length - 2);
                     }

                     obj.EmailContent = body_personal + getFixedMessage2(lbl_Tab.Text, obj.ID.ToString(), Permissions); ;

                     DatabaseHelper.Insert<Tab_ShareActivated>(obj);

                     var LastOrder = (from p in db.UserTabs
                                      where p.UserID == UserKey
                                      orderby p.Order descending
                                      select p.Order).First();
                     LastOrder++;
                     var oUT = new UserTab();
                     oUT.AccessLevel = obj.AccessLevel;
                     oUT.TabId = TabId;
                     oUT.UserID = UserKey;
                     oUT.RoleID = Constants.Role_Individual;
                     DatabaseHelper.Insert<UserTab>(oUT);

                     Email.SendMail(obj.Email, txt_Subject.Text, obj.EmailContent, true);

                     sb.Append("User: " + row["UserName"] + " (" + row["Email"] + ") successfully added<br />");
                     lb.Append("U:" + row["UserName"] + ":" + row["Email"] + ":A|");
                  }
                  else
                  {
                     //make sure the user is not owner of tab
                     UserTab eUT = ut.First();
                     if (eUT.Tab.UserId == UserKey)
                     {
                        sb.Append("Owner: " + row["UserName"] + " (" + row["Email"] + ") permission cannot be changed.<br />");
                        lb.Append("O:" + row["UserName"] + ":" + row["Email"] + ":F|");
                     }
                     else
                     {
                        eUT.AccessLevel = TabAccessLevelFunctions.GeneratePermissionLevel(false,
         (bool)row["Tab_Read"],
         (bool)row["Tab_EditName"],
         (bool)row["Tab_Share"],
         (bool)row["Tab_Delete"],
         (bool)row["Tab_AddWidgets"],
         (bool)row["Tab_ChangeLayout"],
         (bool)row["Tab_ChangeTheme"],
         (bool)row["Widget_Edit"],
         (bool)row["Widget_Reorder"],
         (bool)row["Widget_Delete"],
         (bool)row["Widget_EditTitle"]);
                        sb.Append("User: " + row["UserName"] + " (" + row["Email"] + ") successfully updated<br />");
                        lb.Append("U:" + row["UserName"] + ":" + row["Email"] + ":U|");
                     }
                  }
               }
            }
         }
         using (new TimedLog(Profile.UserName, "Share Tab", lb.ToString()))
         {
            db.SubmitChanges();
         }
         lbl_Results.Text = "<br />" + sb.ToString();
      }
      
      Panel_Confirm.Visible = false;
      Panel_Complete.Visible = true;
   }
   protected void GV_Users_RowDataBound(object sender, GridViewRowEventArgs e)
   {
      if (e.Row.RowType == DataControlRowType.DataRow)
      {
         TextBox txt = (TextBox)e.Row.FindControl("txt_Name");
         DataRowView row = (System.Data.DataRowView)e.Row.DataItem;
         if ((bool)row["isRole"])
         {
            //if is role, then disable edit
            txt.Enabled = false;
            txt.ReadOnly = true;
         }
         else
         {
            txt.Enabled = true;
            txt.ReadOnly = false;
         }
      }
   }
}
